#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
#include "uartinfo.h"
#include "PLL0setup.h"

int PLL0Setup(int PLL_feed, int M, int N, int PLL_output_divider)
{
// PLL0 setup sequence, the following sequence must be followed step by step in order to have PLL0 initialized and running:
// 1. DISCONNECT PLL0 (bit1 PLLC0) with one feed sequence if PLL0 is already connected.
	// A correct feed sequence must be written to the PLL0FEED register in order for changes to
	// the PLL0CON and PLL0CFG registers to take effect. The feed sequence is:
	// 1. Write the value 0xAA to PLL0FEED.
	// 2. Write the value 0x55 to PLL0FEED.
	LPC_SC->PLL0CON &= ~bit1; // Clear bit 1
	 LPC_SC->PLL0FEED = 0xAA; // Feed
	 LPC_SC->PLL0FEED = 0x55;
// 2. DISABLE PLL0 (bit0 PLLE0) with one feed sequence.
	 LPC_SC->PLL0CON &= ~bit0; // Clear bit 0
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
// 3. Change the CPU Clock Divider setting to SPEED UP OPERATION without PLL0, if desired.
	 LPC_SC->CCLKCFG = 0;  // Division par 1 pour vitesse maximum (-1 stocke) -> IRC à 4 MHz =frequence nominale
// 4. Write to the Clock Source Selection Control register to change the clock source if needed.
	 LPC_SC->CLKSRCSEL = PLL_feed; // 0 = IRC, 1 = Main Oscill, 2 = RTC
// 5. Write to the PLL0CFG and make it effective with one feed sequence. The PLL0CFG can only be updated when PLL0 is disabled.
//	 Ici on doit donner le Multiplier et PreDivider

	 //int M = 50-1;
	 //int N = (6-1)<<16;

	 M = M-1;
	  if ( M < 0 ) M = 0;
	 N = N-1;
	  if ( N < 0 ) N=0; // N ne peut pas etre < 0
	 N = N<<16;

	 LPC_SC->PLL0CFG = (M | N); // Fcco = (2*M*Fin)/N = (2*100*4E06)/4 = 200E6
// 6. ENABLE PLL0 with one feed sequence.
	 LPC_SC->PLL0CON |= bit0; // Set bit 0
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
// 7. Change the CPU Clock Divider setting for the operation with PLL0. It is critical to do this before connecting PLL0.
	 if ( PLL_output_divider < 1 ) PLL_output_divider = 1;
	 LPC_SC->CCLKCFG = PLL_output_divider-1; // Sortie PLL0 divisee par PLL_output_divider
// 8. Wait for PLL0 to achieve lock by monitoring the PLOCK0 bit (bit26) in the PLL0STAT register,
// or using the PLOCK0 interrupt, or wait for a fixed time when the input clock to PLL0 is
// slow (i.e. 32 kHz). The value of PLOCK0 may not be stable when the PLL reference
// frequency (FREF, the frequency of REFCLK, which is equal to the PLL input
// frequency divided by the pre-divider value) is less than 100 kHz or greater than
// 20 MHz. In these cases, the PLL may be assumed to be stable after a start-up time
// has passed. This time is 500 μs when FREF is greater than 400 kHz and 200 / FREF
// seconds when FREF is less than 400 kHz.
  int attente = 0;
	 while( (LPC_SC->PLL0STAT & bit26) != bit26 )
		 attente++;
		//printf("Waiting PLL0 locking...\n");
     //printf("PLL0 locked, connecting...\n");
// 9. Connect PLL0 with one feed sequence.
  	 LPC_SC->PLL0CON |= bit1; // Set bit 1
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
	SystemCoreClockUpdate();
 return attente;
}
